#!/bin/sh

# P2P Boot Tool (PBT), by Gabriel Winckler (C) 2009

#	This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.

#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.

#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

# This software has the influence of Clusters for Everyone, by Cicuttin Matteo,
#	a evolution of Hopeless by Christian Pellegrin

# Parameters:
# boot_if = eth0 -- Boot interface
# metalink -- URL to metalink

PATH=/bin:/sbin:/usr/bin:/usr/sbin

initialize()
{
    echo "[*] Mounting /proc, /sys, and making initial device nodes"
    mount -t proc none /proc
    mount -t sysfs none /sys
    
    mknod /dev/null c 1 3
    mknod /dev/zero c 1 5
    mknod /dev/tty c 5 0
    mknod /dev/console c 5 1

    mknod /dev/loop0 b 7 0
    mknod /dev/loop1 b 7 1

    mkdir /dev/pts
    mkdir /dev/shm
    mkdir /sysroot
}

trouble()
{
    echo "The initrd ran into trouble. You can understand something more using this shell"
    sh
}

load_module()
{
    if insmod "$1"
    then
        echo "[*] "$1" loaded"
    else
        echo "[!] Failed to load $1."
        #echo "[!] Failed to load $1. Dropping to a shell"
        #trouble
    fi
}

load_essential_modules()
{
    echo "[*] Loading kernel modules: "
    # Remember that modules need to be loaded in a certain order
    
    # USB drivers (for our drivers this is ok)
    for file in /lib/modules/drivers/usb/*.ko
    do
        load_module "$file"
    done

    insmod /lib/modules/fs/squashfs.ko
    insmod /lib/modules/fs/loop.ko
    
    insmod /lib/modules/fs/exportfs.ko
    insmod /lib/modules/fs/aufs.ko

}

configure_ethernet()
{
    # Load ethernet drivers
    load_module /lib/modules/drivers/net/mii.ko
    for file in /lib/modules/drivers/net/*.ko
    do
        load_module "$file"
    done
    
    ifconfig lo up
    echo "[*] Configuring network interface"
    #udhcpc -i "$BOOT_IF" -q -s /etc/udhcpc.sh
    nash --force /etc/dhcp.nash
}

read_param()
{
    PARAM=`cat /proc/cmdline | grep "$1" | sed "s/.*$1=\([^ ]*\).*/\1/"`

    if ! test $PARAM
    then
        PARAM=$2
    fi

    export $(echo $1 | tr [:lower:] [:upper:])=$PARAM

    echo "[*] - $(echo $1 | tr [:lower:] [:upper:]) = $PARAM"
}

read_kcl()
{
    read_param boot_if eth0
    read_param metalink 
}

download()
{

	echo "[*] Downloading..."
	aria2c -d $2 $1 --seed-time=0

	FILE=$(echo $1 | sed "s/.*\/\([^ ]*\)/\1/")
	export SQUASH=$2/$(aria2c -S $2/$FILE | grep '  1' | cut -d '|' -f 2)

}

mount_filesystems()
{
    echo "[*] Mounting filesystems and preparing for the switchroot"
      
    echo "[*] - RO"
    #sleep 5
    if ! ( mount LABEL=ROOTS /pbt/roots )
    then
		echo "[!] Failed to mount LABEL=ROOTS. Using TMPFS."
		#trouble
		mount -t tmpfs -o size=1G tmpfs /pbt/roots
    fi

	download $METALINK /pbt/roots
	
	echo "[*] Mounting the squash image"
    if ! ( mount -t squashfs -o loop $SQUASH /pbt/root )
	then
		echo "[!] Failed to mount the squash image."
		trouble
	fi

    echo "[*] - RW"
	mount -t tmpfs -o size=256M tmpfs /pbt/node

    echo "[*] Doing the union mount"
    
    AUFS_OPTS="udba=reval,br:/pbt/node:/pbt/root"
    if ! ( mount -t aufs -o "$AUFS_OPTS" aufs /sysroot )
    then
        echo "[!] Union mount failed: $AUFS_OPTS"
        trouble
    fi
}

clear
initialize
load_essential_modules
read_kcl
configure_ethernet
mount_filesystems

if [ ! -f /sysroot/dev/console ]
then
    mknod /sysroot/dev/console c 5 1
fi

# Remove stale lock files
rm -rf /sysroot/var/lock/subsys/*

mount --move /pbt/roots /sysroot/boot/pbt
mount --move /pbt/root /sysroot/boot/pbt/root
mount --move /pbt/node /sysroot/boot/pbt/rw

echo "[*] Runway heading cleared for takeoff, contact tower on /sysroot"
cp /var/lib/dhclient/dhclient.leases /sysroot/var/lib/dhclient/dhclient-$BOOT_IF.leases

exec switch_root -c /dev/console /sysroot /sbin/init

